<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
	<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
	<meta http-equiv="Content-language" content="en" /> 
	<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> 
	<meta name="description" content="RestFB is a simple but powerful Facebook REST API client written in Java" />
	<link rel="canonical" href="http://restfb.com" /> 
	<title>RestFB - A Lightweight Java Facebook REST API Client</title> 	
	<link type="text/css" rel="stylesheet" href="style.css" />	
	<script type="text/javascript" src="jquery-1.4.1.js"></script>	
	<script type="text/javascript" src="prettify.js"></script>
	<script type="text/javascript">
	$(function() {
		prettyPrint();
		
		$("#json-display-link").click(function() {
			$("#json-display").toggle();			
			var text = $(this).text();
			$(this).text($("#json-display").is(":visible")
				? text.replace("see", "hide")
				: text.replace("hide", "see"));								
			return false;
		});
	});
	</script>		
</head>
<body>
	<div id="content">
		<div class="spacer"></div>
	
		<h1>RestFB</h1>
		
		<p>
			RestFB is a simple and flexible <a href="http://wiki.developers.facebook.com/index.php/API">Facebook REST API</a> client written in Java.
		</p>
		
		<div class="spacer"></div>
		
		<h2>Download</h2>
		
		<p>
			Version 1.1 of the library (released Feb 23 2010) is available via Google Code.  <a href="http://restfb.googlecode.com/files/restfb-1.1.zip">Download it here</a>.
		</p>
		
		<p>
			You can also <a href="Example.java">download example code</a> to get started quickly.
		</p>
		
		<div class="spacer"></div>
		
		<h2>Motivations</h2>
		
		<p>
			Design goals:		
			<ul>
				<li>Minimal public API</li>
				<li>Maximal extensibility</li>
				<li>Robustness in the face of frequent Facebook API changes</li>
				<li>Simple metadata-driven configuration</li>
				<li>A single dependency, <a href="http://logging.apache.org/log4j/">Apache Log4j</a></li>			
			</ul> 
		</p> 	
		
		<p>
			Non-goals:		
			<ul>
				<li>Support for non-REST API parts of the Facebook Platform</li>
				<li>Providing a mechanism for obtaining session keys (you must do this yourself via <a href="http://wiki.developers.facebook.com/index.php/Facebook_Connect">Facebook Connect</a>)</li>
				<li>Using XML as a data transfer format in addition to JSON</li>
				<li>Formally-typed versions of all Facebook API methods, error codes, etc.</li>
			</ul>
		</p>
		
		<p>
			If RestFB doesn't meet your needs, <a href="http://wiki.developers.facebook.com/index.php/User:Java">there are some alternative clients available</a>.			
		</p>
		
		<div class="spacer"></div>
		
		<h2>How To Use It</h2>
		
		<p>
			You can jump straight to the <a href="javadoc/index.html">RestFB Javadoc</a>, or learn by example below.
		</p>
		
		<h3>Initialization</h3>
		
		<pre class="prettyprint">
// <a href="javadoc/com/restfb/DefaultFacebookClient.html">DefaultFacebookClient</a> is the <a href="javadoc/com/restfb/FacebookClient.html">FacebookClient</a> implementation
// that ships with RestFB. You can customize it by passing in
// custom <a href="javadoc/com/restfb/JsonMapper.html">JsonMapper</a> and <a href="javadoc/com/restfb/WebRequestor.html">WebRequestor</a> implementations, or simply
// write your own FacebookClient instead for maximum control

FacebookClient facebookClient = new DefaultFacebookClient(MY_API_KEY, MY_SECRET_KEY);</pre>		
		
		<h3>Making a Simple Call</h3>
		
		<p>
			We'll get the <code>UID</code> associated with the current Facebook API session key by calling the API method <code><a href="http://wiki.developers.facebook.com/index.php/Users.getLoggedInUser">users.getLoggedInUser</a></code>.
		</p>	
		
		<pre class="prettyprint">
// Last parameter specifies that this API call's result
// should be returned to us as a Long value

Long uid = facebookClient.<a href="javadoc/com/restfb/FacebookClient.html#execute(java.lang.String,%20java.lang.String,%20java.lang.Class,%20com.restfb.Parameter...)">execute</a>("users.getLoggedInUser", sessionKey, Long.class);</pre>
			
		<h3>Making a More Complex Call</h3>
		
		<p>
			Here we make the API call <code>fql.query</code> to execute a custom query.		
		</p>
		
		<pre class="prettyprint">
// FQL query which asks Facebook for your friends' names,
// profile picture URLs, and network affiliations

String query =
  "SELECT name, pic_big, affiliations FROM user " +
  "WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=12345)";

// Executes an API call with result mapped to a list of classes we've defined.
// Note that you can pass in an arbitrary number of <a href="javadoc/com/restfb/Parameter.html">Parameter</a>s - here we
// send along the query as well as the "give me HTTPS URLs" flag

List&lt;User&gt; users =
  facebookClient.<a href="javadoc/com/restfb/FacebookClient.html#executeForList(java.lang.String,%20java.lang.String,%20java.lang.Class,%20com.restfb.Parameter...)">executeForList</a>("fql.query", sessionKey, User.class,
    Parameter.with("query", query), Parameter.with("return_ssl_resources", "true"));</pre>	
		
		<h3>1. What Happened Under the Covers</h3>
		
		<p>
			The Facebook API returned JSON in response to our query.  You can <a id="json-display-link" href="javascript://">click here to see it</a>.		
		</p>
		
		<pre id="json-display" class="prettyprint" style="display: none;">
[
  {
    "affiliations":
      [
        {
          "nid":50431663,
          "name":"Intuit",
          "type":"work",
          "status":"",
          "year":0
        }
      ],
    "name":"Heather Merlino",
    "pic_big":"https:\/\/secure-profile.facebook.com\/profile6\/138\/106\/n28455_7662.jpg"
  },
  {
    "affiliations":
      [
        {
          "nid":16777221,
          "name":"Cornell",
          "type":"college",
          "status":"Alumnus\/Alumna",
          "year":2004
        },
        {
          "nid":50431762,
          "name":"Bain &amp; Company",
          "type":"work",
          "status":"",
          "year":0
        }
      ],
    "name":"Steve Nolan",
    "pic_big":"https:\/\/secure-profile.facebook.com\/v228\/344\/541\/n4057387_1795.jpg"
  },
  {
    "affiliations":{},
    "name":"Third Person",
    "pic_big":"https:\/\/secure-profile.facebook.com\/v2328\/314\/454\/n137387_5491.jpg"
  }
]</pre>		
		
		<h3>2. Turning JSON into Java</h3>
		
		<p>
			Since RestFB doesn't know in advance what kinds of data you're requesting from the API,
			you need to define your own JavaBean classes that map to API responses. Luckily, this is a simple
			process - just annotate fields with <code><a href="javadoc/com/restfb/Facebook.html">@Facebook</a></code> and RestFB will automatically convert
			Facebook's JSON to real Java objects.
		</p>	
	
		<pre class="prettyprint">
public class User {

  // By default, assumes JSON attribute name is the same as the Java field name  

  @Facebook
  String name;

  // If your Java field name is different than the JSON attribute name,
  // just specify the JSON attribute name
  
  @Facebook("pic_big")
  String pictureUrl;

  // Java doesn't remember generic type information at runtime due to <a href="http://java.sun.com/docs/books/tutorial/java/generics/erasure.html">type erasure</a>.
  // So, for a List type mapping, you have to help out by specifying
  // what kind of type is contained in the List (Affiliation, in this case)
  
  @Facebook(contains = Affiliation.class)
  List&lt;Affiliation&gt; affiliations;

  public String toString() {
    return String.format("Name: %s\nProfile Image URL: %s\nAffiliations: %s",
      name, pictureUrl, affiliations);
  }
}

public class Affiliation {
  @Facebook
  String name;

  @Facebook
  String type;

  public String toString() {
    return String.format("%s (%s)", name, type);
  }
}</pre>
	
		<h3>		
			3. Let's See the Results
		</h3>
		
		<pre class="prettyprint">
for (User user : users)
  System.out.println(user + "\n");</pre> 
		
		<p>	
			And here they are on stdout:
		</p>
		
		<pre>
Name: Heather Merlino
Profile Image URL: https://secure-profile.facebook.com/profile6/138/106/n28455_7662.jpg
Affiliations: [Intuit (work)]

Name: Steve Nolan
Profile Image URL: https://secure-profile.facebook.com/v228/344/541/n4057387_1795.jpg
Affiliations: [Cornell (college), Bain & Company (work)]

Name: Third Person
Profile Image URL: https://secure-profile.facebook.com/v2328/314/454/n137387_5491.jpg
Affiliations: []</pre>
		
		<div class="spacer"></div>		
		
		<h2>Making an fql.multiquery Call (Since 1.1)</h2>

		<p>
			Given the unique nature of the <a href="http://wiki.developers.facebook.com/index.php/Fql.multiquery">fql.multiquery</a> API call,
			RestFB provides the <a href="javadoc/com/restfb/FacebookClient.html#executeMultiquery(java.lang.Class, com.restfb.MultiqueryParameter, com.restfb.Parameter...)">FacebookClient.executeMultiquery(Class, MultiqueryParameter, Parameter...)</a> family of methods
			to easily perform multiquery operations with a minimum of configuration.
		</p>			
		
		<p>
			To use the multiquery support, simply create a map of named queries and create a class to hold the results. Here's an example:
		</p>
		
		<pre class="prettyprint">
FacebookClient facebookClient = new DefaultFacebookClient(API_KEY, SECRET_KEY);

String friendsQuery =
  "SELECT name, pic_big FROM user " +
  "WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=12345)";

String groupsQuery =
  "SELECT gid, name FROM group WHERE gid IN " +
  "(SELECT gid FROM group_member WHERE uid=12345)";

// The key names specified here map to field names in the result object

Map&lt;String, String&gt; queries = new HashMap&lt;String, String&gt;();
queries.put("friends", friendsQuery);
queries.put("groups", groupsQuery);

// You can send along additional parameters if you'd like, too

Results results =
  facebookClient.executeMultiquery(sessionKey, Results.class,
    MultiqueryParameter.with(queries));</pre>
		
		<p>
			Here's the result class and its supporting classes.  By default, results are mapped to <code>@Facebook</code>-annotated fields by the
			logical query name specified in the map. You may override this behavior by explicitly specifying the value as shown below on the <code>users</code> field. 
		</p>
		
		<pre class="prettyprint">
class Results {
  @Facebook(value = "friends", contains = User.class)
  List&lt;User&gt; users;

  @Facebook(contains = Group.class)
  List&lt;Group&gt; groups;
}

// The multiquery support uses the same recursive mapping as the other parts of RestFB.
// It's not shown in this example, but you can create arbitrarily complex object graphs
// of @Facebook-annotated fields to handle complex query results.

class Group {
  @Facebook(value = "gid")
  Long id;

  @Facebook
  String name;
}

class User {
  @Facebook
  String name;

  @Facebook("pic_big")
  String pictureUrl;
}</pre>		
		
		<div class="spacer"></div>		
		
		<h2>JSON Mapping Rules</h2>

		<p>
			Using <code><a href="javadoc/com/restfb/DefaultJsonMapper.html">DefaultJsonMapper</a></code>,
			RestFB is able to recursively map JSON fields annotated with <code>@Facebook</code> to the following Java types out of the box:
		</p>		
		
		<ul>
			<li><code>String</code></li>
			<li><code>Integer</code></li>
			<li><code>Boolean</code></li>
			<li><code>Long</code></li>
			<li><code>Double</code></li>
			<li><code>Float</code></li>
			<li><code>BigInteger</code></li>
			<li><code>BigDecimal</code></li>
			<li>
				Your own JavaBean-compliant classes
				<br/>
				<span class="footnote">
					Don't forget to provide a public default constructor!
				</span>
			</li>
			<li>
				<code>List</code>s of any of the above types
				<br/>
				<span class="footnote">
					Note that, because of type erasure, you must specify what type of object
					is stored in the <code>List</code> via the <code>@Facebook</code> annotation's
					<code>contains</code> attribute or a <code><a href="javadoc/com/restfb/FacebookJsonMappingException.html">FacebookJsonMappingException</a></code> will be thrown at runtime.
					This attribute is ignored if applied to	non-<code>List</code> types.
				</span>				
			</li>
		</ul>
		
		<p>
			For example:	
		</p>
			
		<pre class="prettyprint">
public class MyClass {
  @Facebook
  String name;

  @Facebook
  BigDecimal value;

  @Facebook(contains = Integer.class)
  List&lt;Integer&gt; numbers;
}</pre>			
		
		<p>
			As-is, <code>DefaultJsonMapper</code> should meet the needs of the vast majority of users.
			If it doesn't support a feature you need, you can easily subclass it or write your own implementation of <code><a href="javadoc/com/restfb/JsonMapper.html">JsonMapper</a></code> instead.
		</p>
			
		<div class="spacer"></div>		
		
		<h2>Error Handling</h2>

		<p>					
			All <code><a href="javadoc/com/restfb/FacebookClient.html">FacebookClient</a></code> methods throw the checked, abstract <code><a href="javadoc/com/restfb/FacebookException.html">FacebookException</a></code>.																	
		</p>
		
		<p>
			These are the <code>FacebookException</code> subclasses that you may catch:
		</p>
		
		<ul id="exceptions-list">
			<li>
				<code><a href="javadoc/com/restfb/FacebookJsonMappingException.html">FacebookJsonMappingException</a></code>
				<br/>
				<span class="footnote">					
					Thrown when an error occurs when attempting to map Facebook API response JSON to a Java object.
					It usually indicates that you've used the <code>@Facebook</code> annotation on a field with an unsupported type or
					the Facebook API JSON doesn't map correctly to the fields you've annotated (e.g. attempting to map a JSON string to a Java <code>BigDecimal</code>
					or a JSON object to a Java <code>List</code>).
					
					<div class="spacer"></div>
					
					You generally should not explicitly catch this exception in your code, as it usually signifies programmer
					error in setting up <code>@Facebook</code> annotations.  One valid use for catching this exception,
					however, is to detect when Facebook changes what an API call returns on their end, which would break your live code.
					It may be useful to catch this exception and then send a notification to you or your ops team to notify them
					that your application needs to be updated.
				</span>
			</li>
			<li>
				<code><a href="javadoc/com/restfb/FacebookNetworkException.html">FacebookNetworkException</a></code>
				<br/>
				<span class="footnote">
					Thrown when a failure occurs at the network level.  This can happen if your machine
					doesn't have a network connection or the Facebook API endpoint returns a non HTTP <code>OK</code> (200) status code.
					If there's an HTTP status code available, it's included in the exception so you may take custom actions
					depending on what type of error occurred.
				</span>				
			</li>
			<li>
				<code><a href="javadoc/com/restfb/FacebookResponseStatusException.html">FacebookResponseStatusException</a></code>
				<br/>
				<span class="footnote">
					Thrown when a request is made to Facebook and an HTTP <code>OK</code> (200) response is received, but
					the returned JSON signifies an error condition.
					
					<div class="spacer"></div>
					
					For example, below is the list of errors the Facebook API may return for the <a href="http://wiki.developers.facebook.com/index.php/Stream.removeLike">Stream.removeLike</a> call:
					
					<div class="spacer"></div>					
					<div class="spacer"></div>
					
					<table id="error-table" cellpadding="4" style="border: 1px solid red; margin: 0px; background-color: rgb(255, 153, 153); border-collapse: collapse; border-spacing: 3px; width: 100%;">
					<tbody><tr><td><b>Code</b></td><td><b>Description</b></td>
					</tr><tr valign="top"><th style="font-weight: bold;">100</th><td>  Invalid parameter.  </td><td> 
					</td></tr><tr valign="top"><th style="font-weight: bold;">102</th><td>  Session key invalid or no longer valid (if it's a desktop application and the session is missing).  </td><td>
					</td></tr><tr valign="top"><th style="font-weight: bold;">200</th><td>  Permissions error. The application does not have permission to perform this action.  </td><td>
					</td></tr><tr valign="top"><th style="font-weight: bold;">210</th><td>  User not visible. The user doesn't have permission to act on that object.  </td><td>
					</td></tr></tbody></table>
					
					<div class="spacer"></div>
					<div class="spacer"></div>

					<code>FacebookResponseStatusException</code> will include both the error code and error message returned by the Facebook API
					so you may take custom actions depending on the type of error that occurred.
				</span>				
			</li>
		</ul>
		
		<p>
			Here's some example code to illustrate the above.  Keep in mind that your code doesn't
			need to handle every single exception the way we're doing here - this is just to demonstrate what's possible.
		</p>
		
		<pre class="prettyprint">
try {
  Integer result =
    facebookClient.execute("Stream.removeLike", sessionKey,
      Integer.class, Parameter.with("post_id", "12345"));  
} catch (FacebookJsonMappingException e) {
  // Looks like this API method didn't really return an Integer
} catch (FacebookNetworkException e) {
  // Looks like an error occurred at the network level
  System.out.println("API returned HTTP status code " + e.getHttpStatusCode());
} catch (FacebookResponseStatusException e) {
  // Facebook API returned a specific error
  if (e.getErrorCode() == 200)
    System.out.println("Permission denied!");
} catch (FacebookException e) {
  // This is the catchall handler for any kind of Facebook exception
}</pre>
		
		<div class="spacer"></div>
		
		<h2>Extensibility and Unit Testing</h2>

		<p>
			In addition to <code><a href="javadoc/com/restfb/DefaultFacebookClient.html">FacebookClient</a></code>, RestFB provides default implementations
			for <code><a href="javadoc/com/restfb/DefaultWebRequestor.html">WebRequestor</a></code> and
			<code><a href="javadoc/com/restfb/DefaultJsonMapper.html">JsonMapper</a></code>, two components that
			<code>DefaultFacebookClient</code> depends on to do its work.						
		</p>
		
		<p>
			These dependencies are designed to allow for straightforward subclassing (if you only want to replace a little bit of functionality)
			and simple custom implementations (if you require full control).
		</p>
		
		<p>
			This comes in handy when unit testing - for example, you can write your own <code>WebRequestor</code> implementation
			that simulates a Facebook API endpoint response.  You can drop in custom data designed to exercise your application's
			Facebook integration or simulate error conditions to make sure you're handling them properly.				
		</p>
		
		<p>
			Here's a trivial example which shows one way you might implement this:
		</p>

		<pre class="prettyprint">
FacebookClient facebookClient =
  new DefaultFacebookClient(API_KEY, SECRET_KEY, new DefaultJsonMapper(),
  
    // A one-off <a href="javadoc/com/restfb/WebRequestor.html">WebRequestor</a> for testing that returns a hardcoded JSON
    // list of numbers instead of hitting the Facebook API endpoint URL

    new WebRequestor() {
      public <a href="javadoc/com/restfb/WebRequestor.Response.html">Response</a> <a href="javadoc/com/restfb/WebRequestor.html#executePost(java.lang.String, java.lang.String)">executePost</a>(String url, String parameters) throws IOException {
        return new Response(HttpURLConnection.HTTP_OK, "[123,456,789]");
      }
    });

// Make an API request using the mocked WebRequestor

List<Integer> numbers = facebookClient.<a href="javadoc/com/restfb/FacebookClient.html#executeForList(java.lang.String, java.lang.Class, com.restfb.Parameter...)">executeForList</a>("ignored", Integer.class); 

// Make sure we got what we were expecting

assert numbers.size() == 3;
assert numbers.get(1) == 456;</pre>
			
		<div class="spacer"></div>
		
		<h2>Links</h2>
		
		<p>
			Visit <a href="http://code.google.com/p/restfb">RestFB's home on Google Code</a>.		
		</p>
		
		<p>
			Found a bug or have an enhancement request? <a href="http://code.google.com/p/restfb/issues/list">Create a ticket in the issue tracker</a>.		
		</p>		
		
		<p>
			Download a read-only copy of the current source code using Subversion:		
			<pre>
svn checkout http://restfb.googlecode.com/svn/trunk/ restfb</pre>
		</p>
		
		<div class="spacer"></div>
		
		<h2>About</h2>
		
		<p>
			RestFB is written by <a href="mailto:maa@xmog.com">Mark Allen</a> and sponsored by <a href="http://xmog.com">Transmogrify, LLC</a>. 
		</p>
		
		<div class="spacer"></div>
		
		<h2>Licensing</h2>
		
		<p>
			RestFB is open source software released under the terms of the MIT License:
		</p>
		
		<pre>
Copyright (c) 2010 Mark Allen. 

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.</pre>

		<div class="spacer"></div>		

	</div>
				
	<script type="text/javascript">
		var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
		document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
	</script>
	<script type="text/javascript">
		try {
			var pageTracker = _gat._getTracker("UA-12795899-1");
			pageTracker._trackPageview();
		} catch(err) {}
	</script>
</body>
</html>